﻿using ModbusRTULib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.DataConvertLib;
using System.Threading;
using ControlLib;

namespace ModbusProject
{
    public partial class FrmTHMonitor : Form
    {
        public FrmTHMonitor()
        {
            InitializeComponent();
            InitParam();
        }

        /// <summary>
        /// ModbusRTU通信对象
        /// </summary>
        private ModbusRTU modbus = new ModbusRTU();

        /// <summary>
        /// 当前的连接状态
        /// </summary>
        private bool isConnected = false;

        private System.Threading.CancellationTokenSource cts;

        #region 初始化参数
        /// <summary>
        /// 初始化参数
        /// </summary>
        private void InitParam()
        {
            //获取本机的端口号列表
            string[] portList = SerialPort.GetPortNames();

            if(portList.Length > 0)
            {
                this.cmb_Port.Items.AddRange(portList);
                this.cmb_Port.SelectedIndex = 0;
            }

            //波特率
            this.cmb_BaudRate.Items.AddRange(new string[] { "2400", "4800", "9600", "19200", "38400" });
            this.cmb_BaudRate.SelectedIndex = 2;

            //动态修改ListView第二列的宽度
            this.lst_Info.Columns[1].Width = this.lst_Info.Width - this.lst_Info.Columns[0].Width - 25;
        }
        #endregion

        #region 建立连接与断开连接
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if(isConnected)
            {
                AddLog(1,"温湿度模块已经连接");
            }

            isConnected = modbus.Connect(this.cmb_Port.Text, Convert.ToInt32(this.cmb_BaudRate.Text), Parity.None, 8, StopBits.One);
            if(isConnected)
            {
                AddLog(0, "温湿度模块连接成功");

                //开多线程实时读取
                cts = new CancellationTokenSource();

                Task.Run(() =>
                {
                    Communication();
                },cts.Token);
            }
            else
            {
                AddLog(2, "温湿度模块连接失败");
            }
        }

        private void btn_DisConnect_Click(object sender, EventArgs e)
        {
            //取消消除
            cts?.Cancel();
            modbus.DisConnect();
            isConnected = false;
            AddLog(3, "温湿度模块断开连接");
        }
        #endregion

        #region 多线程实时读取
        private void Communication()
        {
            while(!cts.IsCancellationRequested)
            {
                // 温度对应的地址是40001 温度对应的是40002

                /* //读取一号站点
                 byte[] data = modbus.ReadOutputRegisters(1, 0, 2);

                 if (data != null && data.Length == 4)
                 {
                     this.Invoke(new Action(() =>
                     {
                         this.thMonitor1.Humidity = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                         this.thMonitor1.Temp = ((data[2] * 256 + data[3]) * 0.1f).ToString();
                     }));
                 }

                 //读取二号站点
                 data = modbus.ReadOutputRegisters(2, 0, 2);

                 if (data != null && data.Length == 4)
                 {
                     this.Invoke(new Action(() =>
                     {
                         this.thMonitor2.Humidity = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                         this.thMonitor2.Temp = ((data[2] * 256 + data[3]) * 0.1f).ToString();
                     }));
                 }

                 //读取三号站点
                 data = modbus.ReadOutputRegisters(3, 0, 2);

                 if (data != null && data.Length == 4)
                 {
                     this.Invoke(new Action(() =>
                     {
                         this.thMonitor3.Humidity = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                         this.thMonitor3.Temp = ((data[2] * 256 + data[3]) * 0.1f).ToString();
                     }));
                 }

                 //读取四号站点
                 data = modbus.ReadOutputRegisters(4, 0, 2);

                 if (data != null && data.Length == 4)
                 {
                     this.Invoke(new Action(() =>
                     {
                         this.thMonitor4.Humidity = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                         this.thMonitor4.Temp = ((data[2] * 256 + data[3]) * 0.1f).ToString();
                     }));
                 }*/

                /*ReadTHMonitor(this.thMonitor1);
                ReadTHMonitor(this.thMonitor2);
                ReadTHMonitor(this.thMonitor3);
                ReadTHMonitor(this.thMonitor4);*/

                foreach(var thMonitor in this.Controls.OfType<THMonitor>())
                {
                    ReadTHMonitor(thMonitor);
                }

            }
        }
        #endregion

        #region 封装读取方法
        private void ReadTHMonitor(THMonitor tHMonitor)
        {
            //读取一号站点
            byte[] data = modbus.ReadOutputRegisters(tHMonitor.Devided, 0, 2);

            if (data != null && data.Length == 4)
            {
                tHMonitor.Humidity = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                tHMonitor.Temp = ((data[2] * 256 + data[3]) * 0.1f).ToString();
            }
        }
        #endregion

        #region 通用写入日志的方法
        /// <summary>
        /// 通用写入日志的方法
        /// </summary>
        /// <param name="level"></param>
        /// <param name="info"></param>
        private void AddLog(int level, string info)
        {
            ListViewItem lst = new ListViewItem(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), level);

            lst.SubItems.Add(info);

            //让最新的数据在最上面
            this.lst_Info.Items.Insert(0, lst);
        }

        #endregion
    }
}
